package com.coffee.sku.service.sku.impl;

import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.ExceptionEnum;
import com.coffee.core.enums.SkuSalesInformationTypeEnum;
import com.coffee.core.enums.SkuTypeEnum;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.exception.ValidateBusinessException;
import com.coffee.core.util.BeanUtilExt;
import com.coffee.core.util.DTOUtils;
import com.coffee.core.util.StringUtil;
import com.coffee.order.service.inquire.bean.InquireOrderPlan;
import com.coffee.sku.api.sku.query.SkuCategoryQuery;
import com.coffee.sku.api.sku.req.MerchantSkuListReq;
import com.coffee.sku.api.sku.result.CategoryByAttributeResult;
import com.coffee.sku.api.sku.result.SkuCategoryResult;
import com.coffee.sku.api.sku.service.SkuCategoryService;
import com.coffee.sku.service.sku.bean.Sku;
import com.coffee.sku.service.sku.bean.SkuCategory;
import com.coffee.sku.service.sku.dao.RegionalSkuSalesInformationDao;
import com.coffee.sku.service.sku.dao.SkuCategoryDao;
import com.coffee.sku.service.sku.dao.SkuDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@DubboService(dynamic = true)
public class SkuCategoryServiceImpl implements SkuCategoryService {
    @Resource
    private SkuCategoryDao skuCategoryDao;
    @Resource
    private SkuDao skuDao;
    @Resource
    private RegionalSkuSalesInformationDao regionalSkuSalesInformationDao;

    @Override
    public Page<SkuCategoryResult> getPager(SkuCategoryQuery param, PagerInfo pr) {
        Page<SkuCategoryResult> pager = new Page<SkuCategoryResult>(pr.getStart(), pr.getPageSize());
        Integer count = skuCategoryDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<SkuCategory> list = skuCategoryDao.page(param, pr.getStart(), pr.getPageSize());
            List<SkuCategoryResult> skuCategoryResults = DTOUtils.convertList(list, SkuCategoryResult.class);
            for (SkuCategoryResult skuCategoryResult : skuCategoryResults) {
                SkuCategoryQuery secondParam = new SkuCategoryQuery();
                secondParam.setPid(skuCategoryResult.getId());
                List<SkuCategory> secondList = skuCategoryDao.getList(secondParam);
                if (secondList != null && secondList.size() > 0) {
                    List<SkuCategoryResult> secondCategoryResults = DTOUtils.convertList(secondList, SkuCategoryResult.class);
                    for (SkuCategoryResult secondCategoryResult : secondCategoryResults) {
                        SkuCategoryQuery thirdParam = new SkuCategoryQuery();
                        thirdParam.setPid(secondCategoryResult.getId());
                        List<SkuCategory> thirdList = skuCategoryDao.getList(thirdParam);
                        if (thirdList != null && thirdList.size() > 0) {
                            List<SkuCategoryResult> thirdCategoryResults = DTOUtils.convertList(thirdList, SkuCategoryResult.class);
                            secondCategoryResult.setChildList(thirdCategoryResults);
                        }
                    }
                    skuCategoryResult.setChildList(secondCategoryResults);
                }

            }
            pager.setData(skuCategoryResults);
        }
        return pager;
    }

    @Override
    public Page<CategoryByAttributeResult> getPagerByskuAttribute(SkuCategoryQuery param, PagerInfo pr) {
        Page<CategoryByAttributeResult> pager = new Page<CategoryByAttributeResult>(pr.getStart(), pr.getPageSize());
        Integer count = skuCategoryDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<SkuCategory> list = skuCategoryDao.page(param, pr.getStart(), pr.getPageSize());
            List<CategoryByAttributeResult> skuCategoryResults = DTOUtils.convertList(list, CategoryByAttributeResult.class);
            for (CategoryByAttributeResult skuCategoryResult : skuCategoryResults) {
                SkuCategoryQuery secondParam = new SkuCategoryQuery();
                secondParam.setPid(skuCategoryResult.getId());
                List<SkuCategory> secondList = skuCategoryDao.getList(secondParam);
                if (secondList != null && secondList.size() > 0) {
                    List<SkuCategoryResult> secondCategoryResults = DTOUtils.convertList(secondList, SkuCategoryResult.class);
                    if (secondCategoryResults != null && secondCategoryResults.size() > 0) {
                        List<String> collect = secondCategoryResults.stream().map(SkuCategoryResult::getName).collect(Collectors.toList());
                        skuCategoryResult.setSecondName(collect);
                    }
                }

            }
            pager.setData(skuCategoryResults);
        }
        return pager;
    }

    @Override
    public Integer count(SkuCategoryQuery param) {
        Integer count = skuCategoryDao.count(param);
        return count;
    }

    @Override
    public SkuCategoryResult getDetail(Integer id) {
        SkuCategory item = skuCategoryDao.findById(id);
        if (item == null) {
            return null;
        }
        SkuCategoryResult result = new SkuCategoryResult();
        BeanUtilExt.copyProperties(result, item);
        return result;
    }

    @Override
    public List<SkuCategoryResult> getList(SkuCategoryQuery param, PagerInfo pr) {
        List<SkuCategory> list = skuCategoryDao.page(param, pr.getStart(), pr.getPageSize());
        return DTOUtils.convertList(list, SkuCategoryResult.class);
    }

    @Override
    public List<SkuCategoryResult> getList(SkuCategoryQuery param) {
        List<SkuCategory> list = skuCategoryDao.getList(param);
        List<SkuCategoryResult> skuCategoryResults = DTOUtils.convertList(list, SkuCategoryResult.class);
        for (SkuCategoryResult skuCategoryResult : skuCategoryResults) {
            SkuCategoryQuery secondParam = new SkuCategoryQuery();
            secondParam.setPid(skuCategoryResult.getId());
            List<SkuCategory> secondList = skuCategoryDao.getList(secondParam);
            if (secondList != null && secondList.size() > 0) {
                List<SkuCategoryResult> secondCategoryResults = DTOUtils.convertList(secondList, SkuCategoryResult.class);
                for (SkuCategoryResult secondCategoryResult : secondCategoryResults) {
                    SkuCategoryQuery thirdParam = new SkuCategoryQuery();
                    thirdParam.setPid(secondCategoryResult.getId());
                    List<SkuCategory> thirdList = skuCategoryDao.getList(secondParam);
                    if (thirdList != null && thirdList.size() > 0) {
                        List<SkuCategoryResult> thirdCategoryResults = DTOUtils.convertList(secondList, SkuCategoryResult.class);
                        secondCategoryResult.setChildList(thirdCategoryResults);
                    }
                }
                skuCategoryResult.setChildList(secondCategoryResults);
            }
        }
        return skuCategoryResults;
    }

    @Override
    public List<SkuCategoryResult> getList(String isOnlyFirst) {
        SkuCategoryQuery param = new SkuCategoryQuery();
        List<SkuCategory> skuCategoryList = skuCategoryDao.getList(param);
        Map<Integer, List<SkuCategory>> skuCategoryMap = skuCategoryList.stream().collect(Collectors.groupingBy(SkuCategory::getPid));
        List<SkuCategory> permissions = skuCategoryMap.get(0);
        List<SkuCategoryResult> skuCategoryResults = DTOUtils.convertList(permissions, SkuCategoryResult.class);
        if (!"Y".equals(isOnlyFirst)) {
            recursion(skuCategoryMap, skuCategoryResults);
        }
        return skuCategoryResults;
    }

    public List<SkuCategoryResult> getListNoCity(String isOnlyFirst) {
        SkuCategoryQuery param = new SkuCategoryQuery();
        List<SkuCategory> skuCategoryList = skuCategoryDao.getList(param);
        List<String> categoryPidPaths = skuDao.getCategoryPidPaths();
        Set<Integer> set = new HashSet<>();
        for (String categoryPidPath : categoryPidPaths) {
            String[] split = categoryPidPath.split(",");
            for (String s : split) {
                set.add(Integer.parseInt(s));
            }
        }
        List<SkuCategory> newSkuCategoryList = new ArrayList<>();
        Map<Integer, SkuCategory> integerSkuCategoryMap = skuCategoryList.stream().collect(Collectors.toMap(SkuCategory::getId, i -> i));
        for (Integer integer : set) {
            SkuCategory skuCategory = integerSkuCategoryMap.get(integer);
            if (skuCategory != null) {
                newSkuCategoryList.add(skuCategory);
            }
        }
        newSkuCategoryList = newSkuCategoryList.stream().sorted(Comparator.comparing(SkuCategory::getSort).thenComparing(SkuCategory::getId)).collect(Collectors.toList());
        Map<Integer, List<SkuCategory>> skuCategoryMap = newSkuCategoryList.stream().collect(Collectors.groupingBy(SkuCategory::getPid));
        List<SkuCategory> permissions = skuCategoryMap.get(0);
        List<SkuCategoryResult> skuCategoryResults = DTOUtils.convertList(permissions, SkuCategoryResult.class);
        if (!"Y".equals(isOnlyFirst)) {
            recursion(skuCategoryMap, skuCategoryResults);
        }
        return skuCategoryResults;
    }

    @Override
    public List<SkuCategoryResult> getListByCity(String isOnlyFirst, Integer cityId) {
        if (cityId == null) {
            return getListNoCity(isOnlyFirst);
        } else {
            MerchantSkuListReq req = new MerchantSkuListReq();
            req.setSkuType(SkuTypeEnum.SKU.getCode());
            req.setIsDisable("N");
            req.setIsEnable("Y");
            req.setIsApprove("Y");
            req.setIsDelete("N");
            req.setCityId(cityId);
            req.setType(SkuSalesInformationTypeEnum.GENERAL.getCode());
            Integer skuIdsCount = regionalSkuSalesInformationDao.getSkuIdsCount(req);
            if (skuIdsCount > 0) {
                List<String> categoryPidPaths = regionalSkuSalesInformationDao.getCategoryPidPaths(req);
                Set<Integer> set = new HashSet<>();
                for (String categoryPidPath : categoryPidPaths) {
                    String[] split = categoryPidPath.split(",");
                    for (String s : split) {
                        set.add(Integer.parseInt(s));
                    }
                }
                SkuCategoryQuery param = new SkuCategoryQuery();
                List<SkuCategory> skuCategoryList = skuCategoryDao.getList(param);
                List<SkuCategory> newSkuCategoryList = new ArrayList<>();
                Map<Integer, SkuCategory> integerSkuCategoryMap = skuCategoryList.stream().collect(Collectors.toMap(SkuCategory::getId, i -> i));
                for (Integer integer : set) {
                    SkuCategory skuCategory = integerSkuCategoryMap.get(integer);
                    if (skuCategory != null) {
                        newSkuCategoryList.add(skuCategory);
                    }
                }
                newSkuCategoryList = newSkuCategoryList.stream().sorted(Comparator.comparing(SkuCategory::getSort).thenComparing(SkuCategory::getId)).collect(Collectors.toList());
                Map<Integer, List<SkuCategory>> skuCategoryMap = newSkuCategoryList.stream().collect(Collectors.groupingBy(SkuCategory::getPid));
                List<SkuCategory> permissions = skuCategoryMap.get(0);
                List<SkuCategoryResult> skuCategoryResults = DTOUtils.convertList(permissions, SkuCategoryResult.class);
                if (!"Y".equals(isOnlyFirst)) {
                    recursion(skuCategoryMap, skuCategoryResults);
                }
                return skuCategoryResults;
            } else {
                return getListNoCity(isOnlyFirst);
            }
        }
    }

    public void recursion
            (Map<Integer, List<SkuCategory>> categoryMap, List<SkuCategoryResult> skuCategoryResults) {
        for (SkuCategoryResult skuCategoryResult : skuCategoryResults) {
            Integer id = skuCategoryResult.getId();
            List<SkuCategory> skuCategoryList = categoryMap.get(id);
            if (CollectionUtils.isNotEmpty(skuCategoryList)) {
                List<SkuCategoryResult> submenuList = DTOUtils.convertList(skuCategoryList, SkuCategoryResult.class);
                recursion(categoryMap, submenuList);
                skuCategoryResult.setChildList(submenuList);
            }
        }
    }

    @Override
    public void delete(Integer id) throws BusinessException {
        SkuCategory skuCategory = skuCategoryDao.findById(id);
        Sku sku = skuDao.findByCategoryId(skuCategory.getPidPath());
        if (sku != null) {
            throw BusinessException.build(ExceptionEnum.ERROR_1344);
        }
        skuCategoryDao.deleteById(id);
    }

    @Override
    @Transactional
    public void update(List<SkuCategoryResult> skuCategoryResults) throws BusinessException {
        for (SkuCategoryResult result : skuCategoryResults) {
            SkuCategoryQuery skuCategoryQuery = new SkuCategoryQuery();
            skuCategoryQuery.setNoId(result.getId());
            skuCategoryQuery.setPid(0);
            skuCategoryQuery.setName(result.getName());
            Integer count = skuCategoryDao.count(skuCategoryQuery);
            ValidateBusinessException.assertFalse(count > 0, ExceptionEnum.ERROR_1353);
            ValidateBusinessException.assertNonNull(result.getId(), ExceptionEnum.ERROR_1317);
            SkuCategory item = new SkuCategory();
            BeanUtilExt.copyProperties(item, result);
            SkuCategory tmp = skuCategoryDao.findById(item.getId());
            if (tmp == null) {
                throw new BusinessException(ExceptionEnum.ERROR_0002.getCode(), ExceptionEnum.ERROR_0002.getMessage());
            }
            skuCategoryDao.updateById(item);
        }

    }

    @Override
    public void updateFirstSort(List<Integer> ids) throws BusinessException {
        for (int i = 0; i < ids.size(); i++) {
            SkuCategory tmp = new SkuCategory();
            tmp.setSort(i);
            tmp.setId(ids.get(i));
            skuCategoryDao.updateById(tmp);
        }
    }

    @Override
    public void add(SkuCategoryResult result) throws BusinessException {
        SkuCategoryQuery skuCategoryQuery = new SkuCategoryQuery();
        skuCategoryQuery.setPid(0);
        skuCategoryQuery.setName(result.getName());
        Integer count = skuCategoryDao.count(skuCategoryQuery);
        ValidateBusinessException.assertFalse(count > 0, ExceptionEnum.ERROR_1353);
        SkuCategory skuCategory = new SkuCategory();
        skuCategory.setPid(result.getId() == null ? 0 : result.getId());
        skuCategory.setName(result.getName());
        skuCategory.setSort(0);
        skuCategory.setIcon(result.getIcon());
        skuCategory.setIsOperation("Y");
        skuCategory.setCreateTime(new Date());
        skuCategoryDao.insert(skuCategory);
        if (result.getId() == null) {
            SkuCategory updateCategory = new SkuCategory();
            updateCategory.setId(skuCategory.getId());
            updateCategory.setPidPath(skuCategory.getId() + ",");
            skuCategoryDao.updateById(updateCategory);
        } else {
            SkuCategory skuCategory1 = skuCategoryDao.findById(result.getId());
            SkuCategory updateCategory = new SkuCategory();
            updateCategory.setId(skuCategory.getId());
            updateCategory.setPidPath(skuCategory1.getPidPath() + skuCategory.getId() + ",");
            skuCategoryDao.updateById(updateCategory);
        }

    }

    @Override
    public Map<Integer, SkuCategoryResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, SkuCategoryResult> map = new HashMap<Integer, SkuCategoryResult>();
        List<SkuCategory> list = skuCategoryDao.findByIds(StringUtil.setToList(idSet));
        List<SkuCategoryResult> resultList = DTOUtils.convertList(list, SkuCategoryResult.class);
        for (SkuCategoryResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public Map<Integer, SkuCategoryResult> getItemMap() {
        Map<Integer, SkuCategoryResult> map = new HashMap<Integer, SkuCategoryResult>();
        SkuCategoryQuery param = new SkuCategoryQuery();
        List<SkuCategory> list = skuCategoryDao.page(param, 0, Integer.MAX_VALUE);
        List<SkuCategoryResult> resultList = DTOUtils.convertList(list, SkuCategoryResult.class);
        for (SkuCategoryResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }


}
